<template>
  <div class="tw-multi-transfer">
    <input type="text" readonly :placeholder="placeholder" v-model="inputvalue" @click="handleOpenDialog">
    
  <el-dialog v-model="visible" title="选择谁可以填写" width="800" class="tw-multi-transfer-dialog">
    <template #header>
      <span class="dialog-title">选择谁可以填写</span>
    </template>
    <div class="dialog-body">
      <div class="dialog-body-left">
        <div class="dialog-body-lefthead">
          <el-tabs v-model="activeName" @tab-change="handleClick">
            <el-tab-pane label="组织" name="1"></el-tab-pane>
            <el-tab-pane label="班级" name="3" v-if="orgType!=='1'"></el-tab-pane>
            <el-tab-pane label="用户" name="2"></el-tab-pane>
          </el-tabs>

          <el-tree v-if="activeName === '1'"
            empty-text="暂无数据"
            style="max-width: 400px"
            :props="orgprops"
            ref="orgtreeRef"
            :data="orgList"
            node-key="id"
            show-checkbox
            default-expand-all
            @check-change="handleCheckOrg"
          />

          <div class="class-body" v-else-if="activeName === '3'">
            <div class="tw-search-panel">
              <el-tree-select
              placeholder="请选择组织"
              empty-text="暂无数据"
              v-model="classorg"
              :props="orgprops"
              :data="orgList"
              :height="500"
              check-strictly
              node-key="id"
              default-expand-all
              filterable
              @change="changeClassOrg"
            />
            </div>
            <el-tree 
              empty-text="暂无数据"
              style="max-width: 400px"
              ref="classtreeRef"
              :props="classprops"
              :data="classList"
              node-key="id"
              show-checkbox
              default-expand-all
              @check-change="handleCheckClass"
            />
          </div>
          
          <div class="person-body" v-else>
            <div class="tw-tabpanel-tabs" style="margin-bottom: 10px" v-if="orgType!=='1'">
              <div class="tw-tabpanel">
                <div class="tw-tabitem" @click="activeTab='teacher'" 
                :class="{active: activeTab==='teacher'}">
                  老师
                </div>
                <div class="tw-tabitem" @click="activeTab='student'"
                :class="{active: activeTab==='student'}">
                  学生
                </div>
              </div>
            </div>
            <div class="tw-search-panel">
              <el-tree-select
              placeholder="请选择组织"
              empty-text="暂无数据"
              v-model="classorg"
              :props="orgprops"
              :data="orgList"
              :height="500"
              check-strictly
              node-key="id"
              default-expand-all
              filterable
              @change="changeClassOrg"
            />
            <el-tree-select v-if="activeTab==='student'" class="ml-tiny"
              empty-text="暂无数据"
              placeholder="请选择班级"
              v-model="classvalue"
              :props="classprops"
              :data="classList"
              :height="500"
              check-strictly
              node-key="id"
              default-expand-all
              filterable
              @change="changeClass"
            />
            </div>
            <el-tree v-if="activeTab==='teacher'"
              empty-text="暂无数据"
              style="max-width: 400px"
              ref="teachertreeRef"
              :props="personprops"
              :data="teacherdata"
              node-key="id"
              show-checkbox
              default-expand-all
              filterable
              @check-change="handleCheckTeacher"
            />
              <el-tree v-else
                empty-text="暂无数据"
                style="max-width: 400px"
                ref="studenttreeRef"
                :props="personprops"
                :data="studentdata"
                node-key="id"
                show-checkbox
                default-expand-all
                filterable
                @check-change="handleCheckStudent"
              />
              <!-- <el-tree v-else
                empty-text="暂无数据"
                style="max-width: 400px"
                ref="studenttreeRef"
                :props="personprops"
                :load="loadStudent"
                node-key="id"
                show-checkbox
                default-expand-all
                filterable
                lazy
                @check-change="handleCheckStudent"
              /> -->
          </div>
        </div>
        <div class="dialog-body-leftbody"></div>
      </div>
      <div class="dialog-body-right">
        <div class="dialog-body-righthead">
          <div>已选：{{modelValue.length}}个</div>
          <a @click="clearValue">清空</a>
        </div>
        <div class="dialog-body-rightbody">
          <div class="result-list" v-for="(vitm, idx) in modelValue" :key="idx">
            <div>{{ vitm.name }}</div>
            <div class="xbtn" @click="handleRemove(idx)">
              <i-ep-close></i-ep-close>
            </div>
          </div>
        </div>
      </div>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="visible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">
          确定
        </el-button>
      </div>
    </template>
  </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
import { ElTree, ElMessageBox, ElMessage } from 'element-plus'
import { queryOrgTreeList, queryTeacherList, queryClassList, queryStudentList } from '@/management/api/basedata'
import { purviewSave } from '@/management/api/dataform-extend'
import { arrayToTree } from '@/management/utils/index'
import 'element-plus/theme-chalk/src/message-box.scss'
import 'element-plus/theme-chalk/src/message.scss'
import { CODE_MAP } from '@/management/api/eco/base'

interface Props {
  readonly?: boolean,
  formId: string,
  formConfig: any
}

interface Emit {
  (ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: Array<string> }): void
}

const emit = defineEmits<Emit>()
const props = withDefaults(defineProps<Props>(), {
  readonly: false
})

const modelValue = ref<any[]>([])
const inputvalue = ref('')
const placeholder = computed(() => props.formConfig.placeholder || props.formConfig.label)
const orgType = ref((window as any).$app?.user?.orgType || '2')

const visible = ref(false)

const activeName = ref('1')
const activeTab = ref('teacher')
const classorg = ref('')
const classvalue = ref('')

// tree
interface Tree {
  id: string,
  name: string,
  children?: Tree[]
  isLeaf?: boolean
}
const orgtreeRef = ref<InstanceType<typeof ElTree>>()
const classtreeRef = ref<InstanceType<typeof ElTree>>()
const teachertreeRef = ref<InstanceType<typeof ElTree>>()
const studenttreeRef = ref<InstanceType<typeof ElTree>>()

interface PersonTree {
  id: string
  name: string
  children?: PersonTree[]
}

const orgprops = {
  label: 'name',
  value: 'id',
  children: 'children',
}

const classprops = {
  label: 'name',
  value: 'id',
  children: 'children',
  isLeaf: 'isLeaf',
}

const personprops = {
  label: 'name',
  value: 'id',
  children: 'children',
}

const teacherdata = ref<any>([])
const studentdata = ref<any>([])

const orgList = ref<any>([])
const classList = ref<any>([])

const handleSelectChange = (value: Array<string>) => {
  const key = props.formConfig.key
  
  emit(FORM_CHANGE_EVENT_KEY, { key, value })
}

const handleSubmit = async () => {
  let purviewList: any[] = []
  modelValue.value.forEach((v: any) => {
    if (!['1', '3'].includes(v.nodeType)) {
      purviewList.push({
        objectId: v.id,
        useLimit: activeName.value
      })
    }
  })
  if (purviewList.length === 0) {
    return
  }
  const res: any = await purviewSave({
    formId: props.formId,
    purviewList: purviewList
  })
  if (res?.serverResult?.resultCode === CODE_MAP.SUCCESS) {
    visible.value = false
    inputvalue.value = modelValue.value.map(v => v.name).join(',')
    let newval: any[] = [{
      id: activeName.value,
      value: modelValue.value
    }]
    handleSelectChange(newval)
  } else {
    ElMessage.error(res?.serverResult?.resultMessage || '谁可以填保存失败')
  }
}

const handleClick = () => {
  modelValue.value = []

  let val = props.formConfig?.value || []
  if (val && val.length > 0 && activeName.value === val[0].id) {
    activeName.value = val[0].id
    modelValue.value = val[0].value
  }
}

const handleCheckOrg = (
  data: Tree,
  checked: boolean,
  indeterminate: boolean
) => {
  modelValue.value = (orgtreeRef.value!.getCheckedNodes(false, false) || []).map((titm: any) => {
    return {
      id: titm.id,
      name: titm.name,
      parentId: titm.parentId,
      nodeType: titm.nodeType,
    }
  })
}
const handleCheckClass = (
  data: Tree,
  checked: boolean,
  indeterminate: boolean
) => {
  modelValue.value = (classtreeRef.value!.getCheckedNodes(false, false) || []).map((titm: any) => {
    return {
      id: titm.id,
      name: titm.name,
      parentId: titm.parentId,
      nodeType: titm.nodeType,
    }
  })
}
const handleCheckTeacher = (
  data: PersonTree,
  checked: boolean,
  indeterminate: boolean
) => {
  let selected: any[] = (modelValue.value as Array<any>)?.map((v: any) => v.id) || [];
  (teachertreeRef.value!.getCheckedNodes(false, false) || []).forEach((titm: any) => {
    if (selected.indexOf(titm.id) === -1) {
      modelValue.value.push({
        id: titm.id,
        name: titm.name,
        parentId: titm.parentId,
        nodeType: titm.nodeType,
      })
    }
  })
}
const handleCheckStudent = (
  data: PersonTree,
  checked: boolean,
  indeterminate: boolean
) => {
  let selected: any[] = (modelValue.value as Array<any>)?.map((v: any) => v.id) || [];
  (studenttreeRef.value!.getCheckedNodes(false, false) || []).forEach((titm: any) => {
    if (selected.indexOf(titm.id) === -1) {
      modelValue.value.push({
        id: titm.id,
        name: titm.name,
        parentId: titm.parentId,
        nodeType: titm.nodeType,
      })
    }
  })
}

const handleOpenDialog = async () => {
  if (props.readonly) {
    return
  }
  visible.value = true
  const res: any = await queryOrgTreeList({orgId: (window as any).$app.user.orgId})
  let list = (res?.result || []).map((titm: any) => {
    return {
      id: titm.nodeId,
      name: titm.nodeName,
      ...titm
    }
  })
  let treelist = arrayToTree(list, 'nodeId', 'parentId', 'children')
  treelist.forEach(item => {
    if (!item.children || item.children.length === 0) {
      item.isLeaf = true
    }
  })
  orgList.value = treelist
  if (orgList.value.length > 0) {
    classorg.value = orgList.value[0].id
    getClassList()
    getTeacherList()
  }

  let val = props.formConfig?.value || []
  if (val && val.length > 0) {
    activeName.value = val[0].id
    modelValue.value = val[0].value
    inputvalue.value = modelValue.value.map(v => v.name).join(',')
  }
}

const getClassList = async () => {
  const resp: any = await queryClassList({orgId: classorg.value})
  let classlist = (resp?.pageInfo?.list|| []).map((titm: any) => {
    return {
      id: titm.nodeId,
      name: titm.nodeName,
      ...titm
    }
  })
  let treelistp = arrayToTree(classlist, 'nodeId', 'parentId', 'children')

  treelistp.forEach(item => {
    if (!item.children || item.children.length === 0) {
      item.isLeaf = true
    }
  })
  classList.value = treelistp
}
const getTeacherList = async () => {
  const resp: any = await queryTeacherList({orgId: classorg.value})
  const listp = (resp?.result || []).map((titm: any) => {
    return {
      id: titm.nodeId,
      name: titm.nodeName,
      ...titm
    }
  })
  let treelistp = arrayToTree(listp, 'nodeId', 'parentId', 'children')
  teacherdata.value = treelistp
}

const changeClassOrg = async () => {
  if (activeName.value === '3' || (activeName.value === '2' && activeTab.value === 'student')) {
    await getClassList()
  } else {
    if (activeTab.value === 'teacher') {
      await getTeacherList()
    }
  }
}
const changeClass = async () => {
  const res: any = await queryStudentList({orgId: classvalue.value})
  const list = (res?.pageInfo?.list || []).map((titm: any) => {
    return {
      id: titm.nodeId,
      name: titm.nodeName,
      ...titm
    }
  })

  let treelist = arrayToTree(list, 'nodeId', 'parentId', 'children')
  studentdata.value = treelist
}

const clearValue = async () => {
  if (modelValue.value.length === 0) {
    return
  }
  try {
    await ElMessageBox.confirm('是否确认清除全部选中？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
  } catch (error) {
    return
  }
  modelValue.value = []
}
const handleRemove = async (index: number) => {
  if (modelValue.value.length === 0) {
    return
  }
  try {
    await ElMessageBox.confirm('是否确认清除当前选中？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
  } catch (error) {
    return
  }
  modelValue.value.splice(index)
}

watch(
  () => props.formConfig?.value,
  (val) => {
    if (val && val.length > 0) {
      activeName.value = val[0].id
      modelValue.value = val[0].value
      inputvalue.value = modelValue.value.map(v => v.name).join(',')
    }
  },
  { immediate: true, deep: true }
)
</script>
<style lang="scss">
.tw-multi-transfer-dialog {
  --el-dialog-margin-top: 10vh;
}
</style>
<style lang="scss" scoped>
.tw-multi-transfer {
  display: flex;

  input {
    outline: none;
    background-color: #fff;
    vertical-align: top;
    border: 1px solid #dcdef6;
    width: 440px;
    text-overflow: ellipsis;
    height: 32px;
    transform-origin: left top;
    box-sizing: border-box;
    overflow: hidden;
    color: #6e707c;
    font-size: 14px;
    padding: 12px;
    border-radius: 4px;
  }
}

.tw-multi-transfer-dialog {
  --el-dialog-margin-top: 10vh;
}
:deep(.el-dialog__header) {
  --el-dialog-padding-primary: 0;
}
.dialog-title {
  position: relative;
  margin-left: 12px;
}
.dialog-title::after {
  content: ' ';
  position: absolute;
  left: -12px;
  top: 35%;
  width: 6px;
  height: 6px;
  background: #409eff;
  transform: translateY(-50%);
  transform: rotate(45deg);
}
.dialog-body {
  border: 1px solid #ECECEC;
  border-radius: 12px;
  height: 600px;
  display: flex;
  justify-content: space-between;
}
.dialog-body-left {
  width: 50%;
  border-right: 1px solid #ECECEC;
  height: 100%;
}
.dialog-body-right {
  width: 50%;
  height: 100%;
  padding: 10px 15px;
}

.dialog-body-lefthead {
  width: 100%;
  height: 100%;
  :deep(.el-tabs__nav-wrap.is-top) {
    display: flex;
    justify-content: center;
    width: 100%;
  }

  :deep(.el-tabs__nav-wrap::after) {
    height: 1px;
  }
  :deep(.el-tabs__active-bar) {
    height: 4px;
    border-radius: 2px;
  }
  :deep(.el-tree) {
    height: calc(100% - 55px);
    overflow: auto;
  }
  .class-body {
    height: 100%;

    :deep(.el-tree) {
      height: calc(100% - 98px);
    }
  }
  .person-body {
    height: 100%;

    :deep(.el-tree) {
      height: calc(100% - 138px);
    }
  }
}

.dialog-body-righthead {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-content: center;

  a {
    color: #0081fa;
    cursor: pointer;
  }
}
.dialog-body-rightbody {
  margin-top: 10px;
  max-height: 540px;
  overflow-y: auto;
}
.result-list {
  display: flex;
  justify-content: space-between;
  align-content: center;

  .xbtn {
    cursor: pointer;
  }
  .xbtn:hover {
    color: #0081fa;
  }
}
.tw-tabpanel-tabs {
  display: flex;
  justify-content: center;
}
.tw-tabpanel {
  background: #fff;
  border-radius: 60px;
  border: 1px solid #0081fa;
  display: flex;
  align-items: center;
  padding: 2px;
}
.tw-tabitem {
  border-radius: 56px;
  padding: 0px 20px;
  cursor: pointer;
  font-size: 14px;
  line-height: 26px;

  &:hover {
    color: #0081fa;
  }
}
.tw-tabitem.active {
  background: #0081fa;
  color: #fff;

  &:hover {
    color: #fff;
  }
}

.tw-search-panel {
  padding: 0 15px;
  margin-bottom: 10px;
  display: flex;
}
</style>
